#include "websocket.h"
#include <QTimer>
#include <QtDebug>

WebSocket::WebSocket(QQmlEngine *engine, QObject *parent)
    : QObject(parent)
    , m_engine(engine)
{
    connect(&m_webSocket, &QWebSocket::stateChanged, this, &WebSocket::stateChanged);
    connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &WebSocket::onTextMessageReceived);
}

void WebSocket::open(const QUrl &url)
{
    m_max = 3;
    m_value = 0;

    m_webSocket.open(url);

    emit progressChanged(m_value, m_max);
}

QUrl WebSocket::requestUrl() const
{
    return m_webSocket.requestUrl();
}


void WebSocket::onTextMessageReceived(QString message)
{
    increaseValue();
    QJsonDocument document = QJsonDocument::fromJson(message.toUtf8());

    QJsonObject object = document.object();


    if (object.value("Error").toBool()) {
        qCritical() <<"error:" << object.value("Data").toString();
        emit errorReported(object.value("Data").toString());
        return;
    }


    dispatch(object.value("Data").toVariant().toMap());
}

void WebSocket::stateChanged(QAbstractSocket::SocketState state)
{
    if (state == QAbstractSocket::UnconnectedState)
    {
        finishedProgress();

        emit errorReported("与服务器连接关闭或者无法连接,正在尝试重新连接......");
        m_max = 3;
        m_value = 0;

        QTimer::singleShot(6000, [this](){m_webSocket.open(m_webSocket.requestUrl());});
    }

    else if (state == QAbstractSocket::ConnectingState) {
        increaseValue(1);
    }
    else if (state == QAbstractSocket::ConnectedState) {
        increaseValue(1);
    }

}

bool WebSocket::active()
{
    return m_webSocket.state() == QAbstractSocket::ConnectedState;
}

void WebSocket::post(const QString &action, const QVariantMap &data)
{
    m_value = 0;
    m_max = 3;

    emit progressChanged(m_value, m_max);

    QJsonObject object;

     object.insert("action", action);
     object.insert("data", QJsonObject::fromVariantMap(data));

    QJsonDocument document(object);

    m_webSocket.sendTextMessage(document.toJson());

    increaseValue(1);
}

void WebSocket::dispatch(const QVariantMap &data)
{
    emit readyRead(data.value("Action").toString(), data.value("Data"));
    this->finishedProgress();
}

void WebSocket::increaseValue(int value)
{
    m_value += value;
    emit progressChanged(m_value, m_max);
}

void WebSocket::finishedProgress()
{
    m_value = m_max = 0;
    emit progressChanged(m_value, m_max);
}

